
USE16
queryMemory:
DISPLAY_OFFSET	E820
	xor	ebx,	ebx
	xor	ebp,	ebp		; use for counting
	les	di,	DWORD [MemoryMapAddr]
.queryLoop:
	mov	eax,	0E820h
	mov	edx,	534D4150h	; 'SMAP' ; System memory MAP
	mov	ecx,	24
	mov	DWORD [es:di+20],	1
	int	15h
	jc	queryMemoryError
	cmp	eax,	534D4150h
	jne	queryMemoryError
	
	test	ebx,	ebx		; finish querying if ebx == 0
	jz	.finish
	test	BYTE [es:di+20],	1
	jz	.queryLoop		; ignore the entry
	cmp	ecx,	20
	je	@F
	cmp	ecx,	24
	jne	.queryLoop		; ignore the entry if the length of
					; the returned entry is neither 20 nor 24
@@:	inc	ebp
	add	di,	24
	jmp	.queryLoop

.finish:
	test	BYTE [es:di+20],	1
	jz	.ignoreLast		; ignore the entry
	cmp	ecx,	20
	je	@F
	cmp	ecx,	24
	jne	.ignoreLast		; ignore the entry if the length of
					; the returned entry is neither 20 nor 24
@@:	inc	ebp
.ignoreLast:
	mov	[es:0],	ebp		; entry count
	jmp	queryMemoryEnd

MemoryMapAddr:	dw	4, MEM_MAP_ADDR/16

queryMemoryError:
	mov	si,	.errorTip
	jmp	printError16
.errorTip:	db	'An error occurs when querying memory', 0

INCLUDE "printError16.asm"

queryMemoryEnd:
